package com.centerm.structure.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.centerm.common.constant.Constant;
import com.centerm.common.exception.MyRuntimeException;
import com.centerm.common.view.page.PageQueryResult;
import com.centerm.structure.dao.DepartmentDao;
import com.centerm.structure.dao.UserDao;
import com.centerm.structure.dao.UserRoleDao;
import com.centerm.structure.domain.Department;
import com.centerm.structure.domain.User;
import com.centerm.structure.dto.DepartmentInfo;
import com.centerm.structure.dto.DepartmentTreeInfo;
import com.centerm.structure.dto.UserInfo;
import com.centerm.structure.service.DepartmentService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

/**
 * 
 * @ClassName: DepartmentServiceImpl
 * @Description: 部门服务实现类
 * @author czy
 * @date 2017年8月14日
 */
@Service
public class DepartmentServiceImpl implements DepartmentService {
	@Autowired
	private DepartmentDao departmentDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserRoleDao userRoleDao;

	@Override
	public PageQueryResult<DepartmentInfo> pageDepartmentInfoList(
			Integer pageNum, Integer pageSize, DepartmentInfo departmentInfo) {
		Page<DepartmentInfo> page = PageHelper.startPage(pageNum, pageSize);
		List<Department> list = departmentDao.listByParam(departmentInfo);
		PageQueryResult<DepartmentInfo> resultInfo = new PageQueryResult<DepartmentInfo>(
				page, convertArrayResponse(list));
		return resultInfo;
	}

	@Override
	public List<Department> listDepartmentByParentId(Integer parentId) {
		DepartmentInfo departmentInfo = new DepartmentInfo();
		departmentInfo.setParentId(parentId);
		//只获取有效的记录
		departmentInfo.setValid(1);
		// 根据父节点获取所有子部门
		List<Department> departmentList = departmentDao
				.listByParam(departmentInfo);
		return departmentList;
	}

	@Override
	public List<User> listUserByDepartmentId(Integer departmentId) {
		UserInfo userInfo = new UserInfo();
		userInfo.setDepartment(departmentId);
		//只获取有效的记录
		userInfo.setValid(1);
		// 根据父节点获取所有用户
		List<User> userList = userDao.listByParam(userInfo);
		return userList;
	}

	@Override
	public List<DepartmentTreeInfo> loadDepartmentTree(Integer parentId) {
	    
	    DepartmentInfo temp = new DepartmentInfo();
        temp.setValid(1);
        List<Department> allDepartmentList = departmentDao.listByParam(temp);
        // 获取所有关联的部门ID
        List<Integer> departmentIdList = new ArrayList<>();
        departmentIdList.add(parentId);
        Map<Integer, List<Department>> departmentMap = null;
        if(allDepartmentList != null) {
            departmentMap = convertDepartmentTreeMap(allDepartmentList);
            convertDepartmentId(parentId, departmentIdList, departmentMap);
        }
//        List<UserInfo> userList = userDao.listUserInfoByDepartmentList(departmentIdList);
        // 根据部门分拣userInfo
//        Map<Integer, List<UserInfo>> departmentUserListMap = new HashMap<>();
//	    for(UserInfo user : userList) {
//	        List<UserInfo> list = departmentUserListMap.get(user.getDepartment());
//	        if(list == null) {
//	            list = new ArrayList<>();
//	        } 
//	        list.add(user);
//	        departmentUserListMap.put(user.getDepartment(), list);
//	    }
	    
	    Department department = departmentDao.getById(parentId);
		DepartmentTreeInfo departmentTreeInfo = new DepartmentTreeInfo(department);
		
		converDepartmentTree(parentId, departmentTreeInfo, departmentMap);
		
		List<DepartmentTreeInfo> list = new ArrayList<DepartmentTreeInfo>();
		list.add(departmentTreeInfo);
		return list;
	}
	
	private void converDepartmentTree(Integer rootId, DepartmentTreeInfo rootNode,
	        Map<Integer, List<Department>> departmentMap) {
	    List<DepartmentTreeInfo> treeInfoList = new ArrayList<>();
	    DepartmentTreeInfo subNode = null;
	    if(departmentMap != null) {
            List<Department> subDepartmentList = departmentMap.get(rootId);
            if(subDepartmentList != null) {
                
                for(Department subDepartment : subDepartmentList) {
                    subNode = new DepartmentTreeInfo(subDepartment);
                    if(departmentMap.get(subDepartment.getId()) != null) {
                        converDepartmentTree(subDepartment.getId(), subNode, departmentMap);
                    }
                    treeInfoList.add(subNode);
                }
            }
            rootNode.setChildren(treeInfoList);
        }
	}
	
	@Override
	public List<DepartmentTreeInfo> loadCurrentDepartmentTree(Integer parentId) {
		DepartmentTreeInfo departmentTreeInfo = null;
		List<DepartmentTreeInfo> treeInfoList = new ArrayList<DepartmentTreeInfo>();
		//获取当前部门管理员，以便后面遍历部门人员时为部门管理员打上标识
		Department deparment = departmentDao.getById(parentId);
		Integer currentManager = deparment.getManager();
		try {
			// 组装部门节点
			List<Department> departmentList = listDepartmentByParentId(parentId);
			if(departmentList != null&&departmentList.size()>0){
				for (Department department : departmentList) {
					departmentTreeInfo = new DepartmentTreeInfo(department);
					treeInfoList.add(departmentTreeInfo);
				}
			}
			// 组装用户节点
			List<User> userList = listUserByDepartmentId(parentId);
			if(userList != null&&userList.size()>0){
				for (User user : userList) {
					departmentTreeInfo = new DepartmentTreeInfo(convertUser(user));
					if(currentManager!=null&&currentManager.equals(departmentTreeInfo.getId())){
						departmentTreeInfo.setIsManager(1);
					}
					treeInfoList.add(departmentTreeInfo);
				}
			}
		} catch (Exception e) {
			String errorMsg = "获取树结构错误!";
			throw new MyRuntimeException(errorMsg);
		}
		return treeInfoList;
	}

	@Override
	public Integer insert(DepartmentInfo departmentInfo) {
		Department department = convertRequest(departmentInfo);
		//新增记录必定有效
		department.setValid(1);
		Integer result = departmentDao.insert(department);
		if (result != 1) {
			String errorMsg = "新增部门错误，请排查!";
			throw new MyRuntimeException(errorMsg);
		}
		return department.getId();
	}

	@Override
	public Integer update(DepartmentInfo departmentInfo) {
		Department department = convertRequest(departmentInfo);
		Integer result = departmentDao.update(department);
		if (result != 1) {
			String errorMsg = "更新部门错误，请排查!";
			throw new MyRuntimeException(errorMsg);
		}
		return result;
	}

	@Override
	@Transactional
	public Integer delete(Integer id) {
		List<User> userList = listUserByDepartmentId(id);
		if(userList!=null&&userList.size()>0){
			String errorMsg = "先移除该部门下的所有人员和子部门，才能删除该部门!";
			throw new MyRuntimeException(errorMsg);
		}
		//部门下还有人员的话不能删除部门
		Integer result = departmentDao.deleteById(id);
		if (result != 1) {
			String errorMsg = "删除部门错误，请排查!";
			throw new MyRuntimeException(errorMsg);
		}
		return result;
	}

	@Override
	public DepartmentInfo getById(Integer id) {
		Department department = departmentDao.getById(id);
		return convertResponse(department);
	}

	@Override
	public Boolean isChild(Integer parentId, Integer childId) {
		Boolean b = false;
		//1.parentId为0是顶层根节点，所以必包含；2.相等时也是包含关系
		if(parentId==0||parentId.equals(childId)){
			b = true;
		} else {
			//如果childId为顶层节点，表示遍历完成也没匹配到，退出递归，返回false
			if(childId == 0){
				return false;
			}
			DepartmentInfo departmentInfo = getById(childId);
			b = isChild(parentId,departmentInfo.getParentId());
		}
		return b;
	}
	
	/**
	 * @Description: 判断当前用户是否可管理部门信息
	 * @author czy
	 * @date 2017年8月23日
	 * @param httpSession
	 *            :用户session,departmentId:部门id
	 * @return boolean
	 */
	@Override
	public Boolean isManagerOfDeparment(HttpSession httpSession,
			Integer departmentId) {
		User user = (User) httpSession.getAttribute(Constant.SESSION_USER);
		DepartmentInfo myDepartment = this.getById(user.getDepartment());
		if (!myDepartment.getManager().equals(user.getId())) {
			return false;
		}
		if (!this.isChild(myDepartment.getId(), departmentId)) {
			return false;
		}
		return true;
	}
	
	private Department convertRequest(DepartmentInfo departmentInfo) {
		//TODO czy 该转换方法并不正式，存在风险
		return JSON.parseObject(JSON.toJSONString(departmentInfo),
				Department.class);
	}
	
	private UserInfo convertUser(User user) {
		UserInfo userInfo = JSON.parseObject(JSON.toJSONString(user),
				UserInfo.class);
		//默认非管理员
		userInfo.setIsManager(0);
		return userInfo;
	}

	private DepartmentInfo convertResponse(Department department) {
		//TODO czy 该转换方法并不正式，存在风险
		return JSON.parseObject(JSON.toJSONString(department),
				DepartmentInfo.class);
	}

	private List<DepartmentInfo> convertArrayResponse(
			List<Department> departmentlist) {
		//TODO czy 该转换方法并不正式，存在风险
		return JSON.parseArray(JSON.toJSONString(departmentlist),
				DepartmentInfo.class);
	}

    @Override
    public List<Department> listAll() {
        DepartmentInfo departmentInfo = new DepartmentInfo();
        departmentInfo.setValid(1);
        return departmentDao.listByParam(departmentInfo);
    }

    @Override
    public DepartmentInfo getDetailInfoById(DepartmentInfo department) {
        DepartmentInfo departmentInfo = departmentDao.getDetailInfoById(department.getId());
        
        UserInfo userInfo = new UserInfo();
        userInfo.setValid(1);
        userInfo.setDepartment(department.getId());
        List<UserInfo> userList = userDao.listUserInfoByParam(userInfo, null);
        departmentInfo.setMemberList(userList);
        return departmentInfo;
    }
    
    @Override
    public List<Integer> listDepartmentIdByParentId(Integer parentId) {
        DepartmentInfo temp = new DepartmentInfo();
        temp.setValid(1);
        List<Department> allDepartmentList = departmentDao.listByParam(temp);
        List<Integer> departmentIdList = convertDepartmentIdList(parentId, allDepartmentList);
        return departmentIdList;
    }
    
    /**
     * @Description 根据参数传入的父部门ID和部门列表，筛选出关联的所有子部门的ID
     * @author lk
     * @date 2017年9月5日
     * @param id
     * @param departmentList
     * @return
     */
    private List<Integer> convertDepartmentIdList(Integer id, List<Department> departmentList) {
        List<Integer> departmentIdList = new ArrayList<>();
        departmentIdList.add(id);
        if(departmentList != null) {
            Map<Integer, List<Department>> map = convertDepartmentTreeMap(departmentList);
            convertDepartmentId(id, departmentIdList, map);
        }
        return departmentIdList;
    }
    
    /**
     * @Description 根据部门的上一级部门ID分拣列表
     * @author lk
     * @date 2017年9月1日
     * @param departmentList
     * @return  Map<Integer, List<Department>>
     */
    private Map<Integer, List<Department>> convertDepartmentTreeMap(
            List<Department> departmentList) {
        Map<Integer, List<Department>> parentIdDepartmentMap = new HashMap<>();
        for(Department department : departmentList) {
            if(department.getParentId() != null) {
                List<Department> list = parentIdDepartmentMap.get(department.getParentId());
                if(list == null) {
                    list = new ArrayList<>();
                }
                list.add(department);
                parentIdDepartmentMap.put(department.getParentId(), list);
            }
        }
        
        return parentIdDepartmentMap;
    }

    /**
     * @Description 递归筛选关联的下属部门ID
     * @author lk
     * @date 2017年9月5日
     * @param id
     * @param list
     * @param map
     * @return
     */
    private List<Integer> convertDepartmentId(Integer id,
            List<Integer> list, Map<Integer, List<Department>> map) {
        List<Department> subList = map.get(id);
        if(subList != null) {
            for(Department department : subList) {
                list.add(department.getId());
                if(map.containsKey(department.getId())) {
                    convertDepartmentId(department.getId(), list, map);
                }
            }
        }
        return list;
    }
    
    @Override
    public List<Department> listByManager(Integer manager) {
//        departmentDao.
//        
//        DepartmentInfo temp = new DepartmentInfo();
//        temp.setValid(1);
//        List<Department> allDepartmentList = departmentDao.listByParam(temp);
//        List<Integer> departmentIdList = new ArrayList<>();
//        departmentIdList.add(parentId);
//        if(allDepartmentList != null) {
//            Map<Integer, List<Department>> map = convertDepartmentTreeMap(allDepartmentList);
//            convertDepartmentId(parentId, departmentIdList, map);
//        }
        
        return null;
    }
    
}
